package com.appspot.dojompdft.client;

import java.util.Collection;

import com.appspot.dojompdft.shared.Evento;
import com.appspot.dojompdft.shared.Inscricao;
import com.appspot.dojompdft.shared.LoginInfo;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

public class DojoMPDFT implements EntryPoint {

	private final InscricaoServicoAsync inscricaoServico = GWT.create(InscricaoServico.class);

	final Button botaoInscrever = new Button("Inscrever");
	final Button botaoDesistir = new Button("Desistir");
	final HTML autenticacao = new HTML();

	private LoginInfo loginInfo = null;
	private VerticalPanel loginPanel = new VerticalPanel();
	private Label loginLabel = new Label("Por favor, se autentique com uma conta do Google.");
	private Anchor signInLink = new Anchor("Entrar");
	private Anchor signOutLink = new Anchor("Sair");

	final String eventoId = Window.Location.getParameter("evento");
	final Label nomeEvento = new Label(eventoId);

	EventoServicoAsync eventoService = GWT.create(EventoServico.class);
	AsyncCallback<Evento> eventoAsyncCallback;

	private TextBox descricao = new TextBox();

	private TextBox data = new TextBox();

	private TextBox limite = new TextBox();

	public void onModuleLoad() {

		eventoAsyncCallback = new AsyncCallback<Evento>() {

			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(final Evento evento) {
				
				RootPanel.get("nomeEvento").clear();
				RootPanel.get("erro").clear();
				RootPanel.get("container").clear();
				RootPanel.get("botoesInscricao").clear();
				RootPanel.get("inscritos").clear();

				LoginServicoAsync loginService = GWT.create(LoginServico.class);
				
				loginService.login(Window.Location.createUrlBuilder().buildString(), new AsyncCallback<LoginInfo>() {

					public void onFailure(Throwable error) {
						error.printStackTrace();
					}

					public void onSuccess(LoginInfo result) {
						loginInfo = result;

						if (loginInfo.isLoggedIn()) {
							tela(evento);
						} else {
							loadLogin();
						}
					}

				});

				eventoService.listarTodos(new AsyncCallback<Collection<Evento>>() {

					@Override
					public void onFailure(Throwable caught) {}

					@Override
					public void onSuccess(Collection<Evento> result) {

						if (evento == null) {
							RootPanel.get("container").add(new HTML("<h3>Lista de Eventos</h3><hr />"));

							if (result != null && result.size() > 0) {
								for (Evento e : result) {
									String link = Window.Location.createUrlBuilder().setParameter("evento", e.getId()).buildString();
									RootPanel.get("container").add(new Anchor(e.getDescricao(), link));
									RootPanel.get("container").add(new HTML("<br />"));
								}
							} else {
								RootPanel.get("container").add(new HTML("Não há eventos cadastrados!"));
							}
						}

					}
				});

				if (evento == null) {

					if (eventoId != null && eventoId.length() > 0) {
						RootPanel.get("erro").add(new HTML("<p color=\"red\">O código informado não corresponde a nenhum evento cadastrado!</p>"));
					}

				} else {
					RootPanel.get("nomeEvento").add(new Label(evento.getDescricao()));
					
					botaoInscrever.addClickHandler(new ClickHandler() {
						@Override
						public void onClick(ClickEvent event) {
							inscricaoServico.inscrever(evento.getId(), loginInfo.getEmailAddress(), inscricaoAsyncCallback());
						}
					});

					botaoDesistir.addClickHandler(new ClickHandler() {
						@Override
						public void onClick(ClickEvent event) {
							inscricaoServico.desistir(evento.getId(), loginInfo.getEmailAddress(), inscricaoAsyncCallback());
						}
					});
					
					
					
					
					Collection<Inscricao> inscricoes = evento.getInscricoes();

					if (inscricoes != null && inscricoes.size() == 0) {
						RootPanel.get("inscritos").add(new HTML("<br /><br />Ainda não há inscritos. Seja o primeiro!"));
					} else {
						StringBuffer html = new StringBuffer("<h4>Inscritos</h4><hr /><ol>");

						for (Inscricao i : inscricoes) {
							html.append("<li>" + i.getNome());
						}

						html.append("</ol>");

						RootPanel.get("inscritos").add(new HTML(html.toString()));
					}

				}

			}
		};

		eventoService.obterPelaChave(eventoId, eventoAsyncCallback);

	}

	private void loadLogin() {
		signInLink.setHref(loginInfo.getLoginUrl());
		loginPanel.add(loginLabel);
		loginPanel.add(signInLink);
		RootPanel.get("divAutenticacao").clear();
		RootPanel.get("divAutenticacao").add(loginPanel);
	}
	

	public void tela(final Evento evento) {
		signOutLink.setHref(loginInfo.getLogoutUrl());
		RootPanel.get("divAutenticacao").clear();
		RootPanel.get("divAutenticacao").add(new Label(loginInfo.getNickname()));
		RootPanel.get("divAutenticacao").add(signOutLink);

		if (loginInfo.isUserAdmin()) {
			RootPanel.get("form").clear();

			final FormPanel form = new FormPanel();

			VerticalPanel colunaVertical = new VerticalPanel();
			colunaVertical.add(new HTML("<h3>Novo Evento</h3><hr />"));

			colunaVertical.add(new Label("Descrição:"));
			descricao.setName("descricao");
			colunaVertical.add(descricao);

			colunaVertical.add(new Label("Data:"));
			data.setName("data");
			colunaVertical.add(data);

			colunaVertical.add(new Label("Limite de inscrições"));
			limite.setName("limite");
			colunaVertical.add(limite);

			HorizontalPanel botoes = new HorizontalPanel();

			botoes.add(new Button("Salvar", new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {

					if (descricao.getValue() != null && data.getValue() != null && limite.getValue() != null) {
						if (evento == null) {
							Evento novoEvento = new Evento(descricao.getValue(), data.getValue(), Integer.valueOf(limite.getValue()));

							eventoService.salvar(novoEvento, eventoAsyncCallback);
						} else {
							evento.setDescricao(descricao.getValue());
							evento.setData(data.getValue());
							evento.setLimiteInscricoes(Integer.valueOf(limite.getValue()));

							eventoService.salvar(evento, eventoAsyncCallback);
						}
					}
				}

			}));

			botoes.add(new Button("Excluir", new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					RootPanel.get("inscritos").clear();
					RootPanel.get("botoesInscricao").clear();
					
					eventoService.excluir(evento.getId(), eventoAsyncCallback);
					String link = Window.Location.createUrlBuilder().removeParameter("evento").buildString();
					
					Window.open(link, "_self", "");

				};
			}));

			colunaVertical.add(botoes);
			form.add(colunaVertical);
			colunaVertical.add(new HTML("<br /><br />"));
			RootPanel.get("form").add(form);
		}

		if (evento != null) {
			descricao.setValue(evento.getDescricao());
			data.setValue(evento.getData());
			limite.setValue(String.valueOf(evento.getLimiteInscricoes()));
			
			if (loginInfo != null && loginInfo.isLoggedIn()) {
				HorizontalPanel hp = new HorizontalPanel();
				hp.add(botaoInscrever);
				hp.add(new HTML("&nbsp;&nbsp;"));
				hp.add(botaoDesistir);
				
				RootPanel.get("botoesInscricao").add(hp);
			}
			
		} else {
			descricao.setValue(null);
			data.setValue(null);
			limite.setValue(null);
		}

	}

	private AsyncCallback<String> inscricaoAsyncCallback() {
		return new AsyncCallback<String>() {
			public void onFailure(Throwable caught) {
				caught.printStackTrace();
				// dialogBox.setText("Erro");
				// respostaServidor.setStyleName("serverResponseLabelError");
				// respostaServidor.setHTML("Erro ao gravar os dados.");
				// dialogBox.center();
				// botaoFechar.setFocus(true);
			}

			public void onSuccess(String result) {
				eventoService.obterPelaChave(result, eventoAsyncCallback);
				// dialogBox.setText("Sucesso");
				// respostaServidor.removeStyleName("serverResponseLabelError");
				// respostaServidor.setHTML(result);
				// dialogBox.center();
				// botaoFechar.setFocus(true);
			}
		};
	}
}
